/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package FEMShapeFunctions;

import Integration.IFunction2D;
import MathLib.triangulation.SaveStructures.Node;

/**
 *
 * @author mark
 */
public class FEMShapeFunction1 implements IFunction2D{
    protected Node A;
    protected Node B;
    protected Node C;
    protected double S2;

    private int NodeNum;

    protected double ai ,
                     aj ,
                     ak ;
    protected double bi ,
                     bj ,
                     bk ;
    protected double ci ,
                     cj ,
                     ck ;

    public FEMShapeFunction1(Node A, Node B, Node C) {
            this.A = A;
            this.B = B;
            this.C = C;

            ai = B.x*C.y - C.x*B.y;
            aj = C.x*A.y - A.x*C.y;
            ak = A.x*B.y - B.x*A.y;

            bi = B.y-C.y;
            bj = C.y-A.y;
            bk = A.y-B.y;

            ci = C.x-B.x;
            cj = A.x-C.x;
            ck = B.x-A.x;

            double a =Math.sqrt( ( ck )*(ck) + (bk)*(bk) );   //a-b
            double b =Math.sqrt( (ci)*(ci) + (bi)*(bi) );
            double c =Math.sqrt( (cj)*(cj) + (bj)*(bj) );
            double p = (a+b+c)/2.0;
            S2 =  Math.sqrt( p*(p-a)*(p-b)*(p-c) )*2.0;
        }

        private double Li(double x, double y){
            return (ai+bi*x+ci*y)/S2;
        }

        private double Lj(double x, double y){
            return (aj+bj*x+cj*y)/S2;
        }

        private double Lk(double x, double y){
            return (aj+bj*x+cj*y)/S2;
        }

    public void setNodeNum(int NodeNum) {
        this.NodeNum = NodeNum;
        /**
         * 1 - вузол i;
         * 2 - вузол j;
         * 3 - вузол k;
         */
    }

    public double calculate(double x, double y) {
        //if()
        switch(NodeNum){
            case 1: return Li(x, y);
            case 2: return Lj(x, y);
            case 3: return Lk(x, y);
            default: return 0.0;
        }
    }

    public double calculateDerivatyX(double x, double y) {
        switch(NodeNum){
            case 1: return bi/S2;
            case 2: return bj/S2;
            case 3: return bk/S2;
            default: return 0.0;
        }
    }

    public double calculateDerivatyY(double x, double y) {
        switch(NodeNum){
            case 1: return ci/S2;
            case 2: return cj/S2;
            case 3: return ck/S2;
            default: return 0.0;
        }
    }

    public  double calculateI(double x, double y, int i) {
        //if()
        switch(i){
            case 1: return Li(x, y);
            case 2: return Lj(x, y);
            case 3: return Lk(x, y);
            default: return 0.0;
        }
    }

    public double calculateDerivatyXI(double x, double y, int i) {
        switch(i){
            case 1: return bi/S2;
            case 2: return bj/S2;
            case 3: return bk/S2;
            default: return 0.0;
        }
    }

    public double calculateDerivatyYI(double x, double y, int i) {
        switch(i){
            case 1: return ci/S2;
            case 2: return cj/S2;
            case 3: return ck/S2;
            default: return 0.0;
        }
    }

    public IFunction2D calculateMultFuncs(final int i,final int j){
        return new IFunction2D() {

            public double calculate(double x, double y) {
                return calculateI(x, y, i)*calculateI(x, y, j);
            }
           /**
            *
            *
            * @return the value func i multipled by derivatyX of func j
            */
            public double calculateDerivatyX(double x, double y) {
                return calculateI(x, y, i)*calculateDerivatyXI(x, y, j);
            }
            /**
            *
            *
            * @return the value func i multipled by derivatyY of func j
            */
            public double calculateDerivatyY(double x, double y) {
                return calculateI(x, y, i)*calculateDerivatyYI(x, y, j);
            }
        };
        /*if((i==1)&&(j==2)){
        return new IFunction2D() {

        public double calculate(double x, double y) {
        return Li(x, y)*Lj(x, y);
        }

        public double calculateDerivatyX(double x, double y) {
        return Li(x, y)*bj/S2 + Lk(x, y)*bi/S2;
        }

        public double calculateDerivatyY(double x, double y) {
        return Li(x, y)*cj/S2 + Lk(x, y)*ci/S2;
        }
        };
        }else{
        if((i==1)&&(j==3)){
        return new IFunction2D() {

        public double calculate(double x, double y) {
        return Li(x, y)*Lk(x, y);
        }

        public double calculateDerivatyX(double x, double y) {
        return Li(x, y)*bk/S2 + Lk(x, y)*bi/S2;
        }

        public double calculateDerivatyY(double x, double y) {
        return Li(x, y)*ck/S2 + Lk(x, y)*ci/S2;
        }
        };
        }else{
        return new IFunction2D() {

        public double calculate(double x, double y) {
        return Lj(x, y)*Lk(x, y);
        }

        public double calculateDerivatyX(double x, double y) {
        return Lk(x, y)*bj/S2 + Lj(x, y)*bk/S2;
        }

        public double calculateDerivatyY(double x, double y) {
        return Lk(x, y)*cj/S2 + Lj(x, y)*ck/S2;
        }
        };
        }
        }*/
    }

    /*public IFunction2D calculateMultFuncDeriv(int func,int der){
    return new IFunction2D() {

    public double calculate(double x, double y) {
    return calculateI(x, y, func)*calculateDerivatyX(x, y)
    }

    public double calculateDerivatyX(double x, double y) {
    throw new UnsupportedOperationException("Not supported yet.");
    }

    public double calculateDerivatyY(double x, double y) {
    throw new UnsupportedOperationException("Not supported yet.");
    }
    }
    }*/
}
